package com.gitee.ywj1352.ds;

import com.gitee.ywj1352.ds.aop.annoatation.MyHysitry;
import com.gitee.ywj1352.ds.aop.annoatation.SemaphoreBreaker;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Random;
import java.util.concurrent.*;

/**
 * Created by wenjie.yang on 2019/7/26.
 */
@RestController
public class ServerController {

    private final ExecutorService es = Executors.newSingleThreadExecutor();

    @Value("spring.application.name")
    private String currentServiceName;

    @GetMapping("/hi1")
    public String hi(@RequestParam("msg")String message)throws Exception{
        return sayHi(message);
    }


    //设置 超过 150 mm 就 熔断 call fallback熔断方法
    @HystrixCommand(fallbackMethod = "errorContent",
            commandProperties = {@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds",
            value = "150")}
    )
    @GetMapping("/say")
    public String say(@RequestParam("msg")String message)throws Exception{
        return sayHi(message);
    }

    private String sayHi(@RequestParam("msg") String message) throws InterruptedException {
        Random random = new Random();
        int i = random.nextInt(100);
        Thread.sleep(Long.valueOf(i)+100L);
        System.out.println("Service Controller 接受到 -say "+ message);
        return " hello ," + message;
    }

    public String errorContent(String message){
        return message;
    }
    //垃圾版
    @GetMapping("/say2")
    public String say2(@RequestParam("msg")String message)throws Exception{
        long startTime= System.currentTimeMillis();
        String returnValue = sayHi(message);
        long endTime= System.currentTimeMillis();
        long costTime = endTime - startTime;
        if (costTime>150){
            throw new TimeoutException("执行超时");
        }
        return returnValue;
    }
    //低版本 无容错实现
    @GetMapping("/say3")
    public String say3(@RequestParam("msg")String message)throws Exception{
        Future<String> submit = es.submit(() -> {
            return sayHi(message);
        });
        //给你 150 毫秒超时
        String returnValue;
        //容错
        try {
            returnValue = submit.get(150, TimeUnit.MILLISECONDS);
        }catch (TimeoutException e){
            submit.cancel(true);
            returnValue= errorContent(message);
        }
        return returnValue;
    }

    //代码都有倾入性
    @GetMapping("/say4")
    public String say4(@RequestParam("msg")String message)throws Exception{
        Future<String> submit = es.submit(() -> {
            return sayHi(message);
        });
        //给你 150 毫秒超时
        String  returnValue = submit.get(150, TimeUnit.MILLISECONDS);
        return returnValue;
    }

    //使用线程池
    @MyHysitry("error")
    @GetMapping("/advanceSay")
    public String advanceSay(@RequestParam("msg")String message)throws Exception{
        return say(message);
    }


    //使用信号量
    @SemaphoreBreaker(5)
    @GetMapping("/advanceSay2")
    public String advanceSay2(@RequestParam("msg")String message)throws Exception{
        return say(message);
    }


}
